package com.ac.api.user.controller;

import com.ac.api.userinfo.entity.AcUserinfo;
import com.ac.api.userinfo.service.AcUserinfoService;
import com.ac.utils.JWTUtil;
import com.ac.utils.PasswordUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.annotation.SysLog;
import com.base.annotation.Unsecured;
import com.base.context.Context;
import com.base.context.ContextHolder;
import com.base.helper.BaseController;
import com.base.helper.PwdCheckUtil;
import com.base.helper.Result;
import com.base.helper.StringUtils;
import com.ac.api.group.entity.AcGroup;
import com.ac.api.group.service.AcActionPageService;
import com.ac.api.group.service.AcGroupService;
import com.ac.api.user.entity.AcUser;
import com.ac.api.user.service.AcLoginlogService;
import com.ac.api.user.service.AcUserService;
import com.ac.api.user.vo.*;
import com.ac.config.UserConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.*;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author mzl
 * @since 2020-07-09
 */
@Api(tags = "用户")
@RestController
@RequestMapping("/acUser")
public class AcUserController extends BaseController {

    private static final Logger              LOG = LoggerFactory.getLogger(AcUserController.class);
    @Autowired
    private              AcUserService       entityService;
    @Autowired
    private              AcGroupService      acGroupService;
    @Autowired
    private              AcActionPageService acActionPageService;
    @Autowired
    private AcUserinfoService acUserinfoService;
    @Autowired
    private              UserConfig          userConfig;
    @Autowired
    private              AcLoginlogService   acLoginlogService;

    @SysLog(action = "acUser:delete", value = "用户管理：删除用户")
    @ApiOperation(value = "删除用户")
    @RequestMapping(value = "{id}", method = {RequestMethod.DELETE})
    @ApiImplicitParam(name = "id", value = "用户ID", required = true, paramType = "path")
    public Result delete(@PathVariable final Integer id) {
        AcUser acUser = entityService.getById(id);
        if (null == acUser) {
            throw new RuntimeException("没有找到Id对应对象");
        }
        acUser.setState(0);
        entityService.updateById(acUser);
        return new Result(true, "成功删除用户", null);
    }

    @SysLog(action = "acUser:one", value = "用户管理：查询用户详细")
    @ApiOperation(value = "查询单个用户")
    @RequestMapping(value = "{id}", method = {RequestMethod.GET})
    @ApiImplicitParam(name = "id", value = "用户ID", required = true, paramType = "path")
    public Result one(@PathVariable final Integer id) {
        AcUser entity = entityService.getById(id);
        return new Result(true, entity);
    }

    @SysLog(action = "acUser:add", value = "用户管理：添加用户")
    @ApiOperation(value = "添加用户")
    @PostMapping("/add")
    public Result add(@Valid @RequestBody final AcUser entity) throws Exception {
        AcUser acUser=entityService.getOne(
                new QueryWrapper<AcUser>()
                        .eq("'username'",entity.getUsername())
                        .eq("'state'", 1)
        );
        if(acUser!=null){
            return new Result(false, "添加失败，该账号已存在！", null);
        }
            entity.setState(1);
            entity.setCreatetime(new Date());
//            entity.setTeacherNumber(entity.getUsername());
            entity.setPassword(entity.getPassword());
        entityService.save(entity);
        return new Result(true, "成功保存用户", null);
    }

    @SysLog(action = "acUser:update", value = "用户管理：修改用户")
    @ApiOperation(value = "修改用户")
    @RequestMapping(method = {RequestMethod.PUT})
    public Result update(@Valid @RequestBody final AcUser entity) {
        if (null == entity.getId()) {
            throw new RuntimeException("id不能为空");
        }
        if (entity.getPassword() != null){
            entity.setPassword(PasswordUtil.encrypt(entity.getPassword(),"peakfit"));
        }
        entityService.updateById(entity);
        return new Result(true, "成功修改用户", null);
    }


    @SysLog(action = "acUser:login", value = "用户管理：【用户】登录")
    @ApiOperation(value = "【用户】登录")
    @PostMapping(value = "login")
    @Unsecured
    public Result<LoginSuccessVo> login(@Valid @RequestBody final LoginVo login) {
        Context context = ContextHolder.currentContext();
        AcUser user = entityService.findByUsername(login.getUsername());
        if (null == user) {
            acLoginlogService.addLog(null, login.getUsername(), "f", "该账号不存在");
            return new Result(false, "该账号不存在", "该账号不存在");
        }
     else {
         if(user.getPassword().equals(login.getPassword())) {
             return new Result<>(true, normalizeContext(context,user));
         }
         else{
             acLoginlogService.addLog(user.getId(), login.getUsername(), "f", "账号或密码不正确");
             return new Result(false, "账号或密码不正确", "账号或密码不正确");
         }
        }

    }

    private LoginSuccessVo normalizeContext(Context context, AcUser user) {
        AcUserVo vo      = new AcUserVo(user);
        user.setPassword(null);

        Map<String, Object> claims = new HashMap<>();
        claims.put("id", vo.getId());
        claims.put("username", vo.getUsername());
        claims.put("roleid", vo.getRoleid());
        String token = JWTUtil.genToken(claims);
        return new LoginSuccessVo(user,token);
    }

    @SysLog(action = "acUser:logout", value = "用户管理：【用户】注销")
    @ApiOperation(value = "【用户】注销")
    @RequestMapping(value = "logout", method = GET)
    public Result logout(HttpServletResponse response) {
        Cookie cookie = new Cookie("token", "");
        cookie.setPath("/");
        cookie.setMaxAge(0);
        // 写回cookie
        response.addCookie(cookie);
        //
        if (LOG.isDebugEnabled()) {
            LOG.debug("token[{}]写回cookie", "");
        }
        return new Result(true, "退出成功", null);
    }

    @SysLog(action = "acUser:resetPwd", value = "用户管理：修改密码")
    @ApiOperation(value = "修改密码")
    @RequestMapping(value = "{username}/pwdreset", method = POST)
    @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "username", required = true, paramType = "path")})
    public Result resetPwd(@PathVariable("username") String username, @Valid @RequestBody final ResetPwdVo pwdVo,
                           final BindingResult result) {
        AcUser user = entityService.getOne(new QueryWrapper<AcUser>().eq("username",username));
         user.setPassword(pwdVo.getPwd());
            entityService.updateById(user);
            return Result.SUCCESS;
    }

    @SysLog(action = "acUser:pwdCheck", value = "用户管理:校验密码")
    @ApiOperation(value = "校验密码")
    @RequestMapping(value = "/pwdCheck", method = {RequestMethod.POST})
    public Result pwdCheck(@Valid @RequestBody final AcCheckPwdVo acCheckPwdVo) {
        return new PwdCheckUtil().checkPassword(acCheckPwdVo.getPwd());
    }

    @SysLog(action = "acUser:setStatus", value = "用户管理：设置用户状态")
    @ApiOperation(value = "设置用户状态")
    @RequestMapping(value = "{id}/set/{enable}", method = {RequestMethod.POST})
    @ApiImplicitParams({@ApiImplicitParam(name = "enable", value = "用户状态：1启用，0禁用", required = true, paramType = "path"
    )})
    public Result<AcUser> setStatus(@PathVariable(name = "id") final Integer id,
                                    @PathVariable(name = "enable") String enable) {
        Context context = ContextHolder.currentContext();
        if ("1".equals(enable) || "0".equals(enable)) {
            AcUser acUser = entityService.setEnable(id, enable);
            return new Result<>(true, acUser);
        } else {
            return new Result<>(true, "设置用户状态失败", "设置参数非法，只能设置为0或1");
        }
    }

}
